﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using PromotionApp.Utility;
using PromotionApp.Model;
using PromotionApp.BLL;
using System.Text;
using System.Text.RegularExpressions;
using CKEditor.NET;

namespace PromotionApp.UserControl
{
    public partial class ucPost : System.Web.UI.UserControl
    {
        #region Private Variable

        private readonly string _TopicListUrl = "TopicList.aspx";
        private readonly string _EmailPattern = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";

        #endregion

        #region Public Variable

        public event EventHandler OnPostedMessage = null;

        #endregion

        #region Propety

        public int TopicId
        {
            get
            {
                int topicId = 0;

                if (ViewState["TopicId"] != null)
                    topicId = Convert.ToInt32(ViewState["TopicId"]);

                return topicId;
            }
            set
            {
                ViewState["TopicId"] = value;
            }
        }

        public int CategoryId
        {
            get
            {
                int categoryId = 0;

                if (ViewState["CategoryId"] != null)
                    categoryId = Convert.ToInt32(ViewState["CategoryId"]);

                return categoryId;
            }
            set
            {
                ViewState["CategoryId"] = value;
            }
        }

        public string CategoryName
        {
            get
            {
                string strCategoryName = string.Empty;

                if (ViewState["CategoryName"] != null)
                    strCategoryName = ViewState["CategoryName"].ToString().Trim();

                return strCategoryName;
            }
            set
            {
                ViewState["CategoryName"] = value;
            }
        }

        public string IsTopic
        {
            get
            {
                string strIsTopic = string.Empty;

                if (ViewState["IsTopic"] != null)
                    strIsTopic = ViewState["IsTopic"].ToString().Trim();

                return strIsTopic;
            }
            set
            {
                ViewState["IsTopic"] = value;
            }
        }

        public PostType Post
        {
            get
            {
                PostType post = 0;

                if (ViewState["Post"] != null)
                    post = (PostType)(ViewState["Post"]);

                return post;
            }
            set
            {
                ViewState["Post"] = value;
            }
        }

        public string Identity
        {
            get
            {
                string strIdentity = string.Empty;

                if (ViewState["Identity"] != null)
                    strIdentity = ViewState["Identity"].ToString().Trim();

                return strIdentity;
            }
            set
            {
                ViewState["Identity"] = value;
            }
        }

        #endregion

        #region Private Method

        private void ValidateImageFile(string fileName, int fileSize)
        {
            if (fileName.Trim().Length > 0)
            {
                string extension = Path.GetExtension(fileName).ToLower();

                if (!(extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || extension.Equals(".png", StringComparison.OrdinalIgnoreCase) || extension.Equals(".gif", StringComparison.OrdinalIgnoreCase)))
                    throw new InvalidOperationException("Invalid image file.");
                else if (fileSize > ConfigurationHelper.ImageSize)
                    throw new InvalidOperationException("invalid file size.");
            }
        }

        private string UploadImage()
        {
            string strImageUrl = string.Empty;

            if (this.fulImage.HasFile)
            {
                string strFileName = string.Format("{0}_{1}", DateTimeHelper.GetDateTimePrefix(), this.fulImage.FileName);
                strImageUrl = PageHelper.GetImageUrl(this.Request.Url.AbsoluteUri, strFileName);
                string filePath = string.Format(@"{0}\{1}", Server.MapPath(ConfigurationHelper.UploadImageFolder), strFileName);
                this.fulImage.SaveAs(filePath);
            }

            return strImageUrl;
        }

        private string UploadImageFile()
        {
            ValidateImageFile(this.fulImage.FileName, this.fulImage.PostedFile.ContentLength);

            return UploadImage();
        }

        private void SetIdentity(Post post)
        {
            if (Regex.IsMatch(this.Identity, this._EmailPattern))
                post.Email = this.Identity;
            else
                post.UserName = this.Identity;
        }

        private Topic GetTopic()
        {
            Topic topic = new Topic();

            topic.CategoryId = this.CategoryId;
            topic.TopicDescription = this.tbxTopic.Text.Trim();
            topic.Message = this.CKEditor1.Text;
            topic.ImagePath = UploadImageFile();
            topic.StatusCode = "E";
            SetIdentity(topic);

            return topic;
        }

        private Reply GetReply()
        {
            Reply reply = new Reply();

            reply.TopicId = this.TopicId;
            reply.Message = this.CKEditor1.Text.Trim();
            reply.ImagePath = UploadImageFile();
            reply.StatusCode = "E";
            SetIdentity(reply);

            return reply;
        }

        private void ResetControl()
        {
            this.tbxTopic.Text = string.Empty;
            this.CKEditor1.Text = string.Empty;
        }

        private void PostTopic()
        {
            Topic topic = GetTopic();
            TopicBLL.GetInstance().AddTopic(topic);
            PageHelper.AlertMessageAndRedirect("Post Topic Completed.", string.Format("{0}?categoryId={1}&categoryName={2}", this._TopicListUrl, this.CategoryId, this.CategoryName), this.Page);
        }

        private void PostReply()
        {
            Reply reply = GetReply();
            ReplyBLL.GetInstance().AddReply(reply, this.CategoryId);
            ResetControl();

            if (this.OnPostedMessage != null)
                this.OnPostedMessage(this, new EventArgs());

            PageHelper.AlertMessage("Post Reply Completed.", this.Page);
        }

        private void PostMessage()
        {
            try
            {
                switch (this.Post)
                {
                    case PostType.Topic:
                        PostTopic();
                        break;
                    case PostType.Reply:
                        PostReply();
                        break;
                    default:
                        throw new ApplicationException("Invalid Oparation.");
                }
            }
            catch (Exception ex)
            {
                PageHelper.AlertMessage(ex.Message, this.Page);
            }
        }

        private void InitializeEditor()
        {
            this.CKEditor1.config.uiColor = "#75A619";
            this.CKEditor1.config.enterMode = EnterMode.BR;
            this.CKEditor1.config.resize_enabled = false;
            this.CKEditor1.config.toolbar = new object[]
            {
                new object[] { "Source", "Preview" },
                new object[] { "Cut", "Copy", "Paste", "PasteText", "PasteFromWord" },
                new object[] { "Undo", "Redo", "-", "Find", "Replace", "-", "SelectAll", "RemoveFormat" },                                
                new object[] { "Bold", "Italic", "Underline", "Strike", "-", "Subscript", "Superscript" },
                new object[] { "NumberedList", "BulletedList", "-", "Outdent", "Indent", "Blockquote", "CreateDiv" },
                "/",
                new object[] { "JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock" },
                new object[] { "BidiLtr", "BidiRtl" },
                new object[] { "Link", "Unlink", "Anchor" },
                new object[] { "Image", "Table", "HorizontalRule", "Smiley", "SpecialChar" },                
                new object[] { "Styles", "Format", "Font", "FontSize" },
                new object[] { "TextColor", "BGColor" },                
            };
        }

        private void Initialize()
        {
            if (this.Post == PostType.Reply)
            {
                this.trTopicSeparator.Visible = false;
                this.trTopic.Visible = false;
            }
        }

        #endregion

        #region Event

        protected void Page_Load(object sender, EventArgs e)
        {
            InitializeEditor();

            if (!this.IsPostBack)
            {
                try
                {
                    Initialize();
                }
                catch (Exception ex)
                {
                    PageHelper.AlertMessage(ex.Message, this.Page);
                }
            }
        }

        protected void btnPost_Click(object sender, EventArgs e)
        {
            try
            {
                PostMessage();
            }
            catch (Exception ex)
            {
                PageHelper.AlertMessage(ex.Message, this.Page);
            }
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                this.Page.Response.Redirect(string.Format("{0}?categoryId={1}&categoryName={2}", this._TopicListUrl, this.CategoryId, this.CategoryName));
            }
            catch (Exception ex)
            {
                PageHelper.AlertMessage(ex.Message, this.Page);
            }
        }

        #endregion
    }
}